#pragma once

#include "Team.h"
#include "Classification.h"
#include "Serializable.h"
#include "LeagueSettings.h"
#include "LeagueCalendar.h"

#include "LeagueHistory.h"

#include "StlStringAndStreams.h"

class ServiceProvider;

class League : public Serializable
{
public:
	
	League(ServiceProvider* i_sp);
	~League();

	void Clear();
	void Initialize(STL::string& name, LeagueSettings& i_settings); 
	void Update(const bool i_doNotPrompt);
	bool IsEnded() const;
	void EndSeasonUpdate(const bool i_doNotPrompt, STD::stringstream& o_message);

	const LeagueCalendar*	GetCalendar() const;
	const Classification* GetClassification() const;

	const int GetID() const {return m_id;}
	void SetID(const int i_id) {m_id = i_id;}

	const TeamVec& GetTeams() const;
	TeamVec& GetTeams();
	
	const MatchDataVec& GetLastPlayedTurn() const;
	const STL::string& GetName() const;
	
	const LeagueSettings& GetSettings() const;

	const LeagueHistory& GetHistory() const;
	
	int GetNumPromoted() const;
	int GetNumDemoted() const;

	void SortTeams();

	/**
		Return the index of this team in the sorted classification (0 is the top)
		if the team isn't into the container return -1
	*/
	int GetTeamPosition(Team const * const i_team);

	//da commentare bene
	bool RemoveFirstOrLastTeams(TeamVec& o_removed, size_t i_numToRemove, bool i_removeFromEnd = true);
	
	void RemoveBankruptTeam(Team* const io_bankruptTeam);

	int GetLayerIndex() const;

	virtual	ZStream& Serialize(ZStream& o_stream) const;
	virtual ZStream& Deserialize(ZStream& i_stream);

	static const int	MAX_LEAGUE_NAME_SIZE = 25;

private:
	//copy disabled
	League(const League&); 
	League& operator=(const League&);

	void				Restart();

	STL::string			m_leagueName;
	LeagueSettings		m_settings;
	TeamVec				m_teams;
	TeamVec				m_sortedTeams;
	Classification		m_classification;
	LeagueCalendar		m_calendar;
	MatchDataVec		m_lastPlayedTurn;
	ServiceProvider*	m_sp;
	int					m_id;
	LeagueHistory		m_history;

	friend class LeagueLayer;
	friend class LeagueManager;
};

inline const LeagueCalendar* League::GetCalendar() const
{
	return &m_calendar;
}

inline const Classification* League::GetClassification() const
{
	return &m_classification;
}

inline const TeamVec& League::GetTeams() const
{
	return m_teams;
}

inline const LeagueHistory& League::GetHistory() const
{
	return m_history;
}

inline TeamVec& League::GetTeams()
{
	return m_teams;
}

inline const MatchDataVec& League::GetLastPlayedTurn() const
{
	return m_lastPlayedTurn;
}

inline const STL::string& League::GetName() const
{
	return m_leagueName;
}

inline const LeagueSettings& League::GetSettings() const
{
	return m_settings;
}

inline int League::GetLayerIndex() const
{
	return m_settings.layerIndex;
}

inline int League::GetNumPromoted() const
{
	return m_settings.numPromoted;
}

inline int League::GetNumDemoted() const
{
	return m_settings.numDemoted;
}
